#include "mainwindow.h"
#include <QVBoxLayout>
#include <QProgressBar>
#include <QGroupBox>
#include <QThreadPool>
#include <QLabel>
#include "library.h"
#include "reader.h"
#include "writer.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QGroupBox *box = new QGroupBox();
    QLayout *layout = new QVBoxLayout();
    box->setLayout(layout);

    int shelfCapacity = 100;
    int readerThreadNumber = 50;
    int writerThreadNumber = 50;
    int readerReadingTime = 1000;
    int readerSleepingTime = 1400;
    int writerWritingTime = 1000;
    int writerEditingTime = 1400;
    int writerSleepingTime = 1400;

    int threadNumber = readerThreadNumber + writerThreadNumber;

    // number of books
    m_shelfUsage = new QProgressBar(this);
    layout->addWidget(new QLabel("Shelf usage"));
    layout->addWidget(m_shelfUsage);
    m_shelfUsage->setMaximum(shelfCapacity);

    // number of readers and writers
    m_threadsActive = new QProgressBar(this);
    layout->addWidget(new QLabel("Active threads"));
    layout->addWidget(m_threadsActive);
    m_threadsActive->setMaximum(threadNumber);

    // number of waiting readers and writers
    m_threadsWaiting = new QProgressBar(this);
    layout->addWidget(new QLabel("Waiting threads"));
    layout->addWidget(m_threadsWaiting);
    m_threadsWaiting->setMaximum(threadNumber);

    setCentralWidget(box);

//    m_shelfUsage->setValue(30);
    Library *library = new Library(shelfCapacity);
    connect(library, SIGNAL(finishedWritingBook()), this, SLOT(shelfUsageIncreased()));
    connect(library, SIGNAL(waitingForBook()), this, SLOT(waitingThreadNumberIncreased()));
    connect(library, SIGNAL(finishedEditingBook()), this, SLOT(waitingThreadNumberDecreased()));

    QThreadPool* pool = QThreadPool::globalInstance();
    pool->setMaxThreadCount(threadNumber);

    for (int i = 0; i < writerThreadNumber; ++i)
    {
        pool->start(new Writer(i, library, writerWritingTime,
                                           writerEditingTime,
                                           writerSleepingTime));
    }
    for (int i = 0; i < readerThreadNumber; ++i)
    {
        pool->start(new Reader(i, library, readerReadingTime,
                                           readerSleepingTime));
    }

}

void MainWindow::shelfUsageIncreased()
{
    m_shelfUsage->setValue(m_shelfUsage->value() + 1);
}

void MainWindow::waitingThreadNumberIncreased()
{
    m_threadsWaiting->setValue(m_threadsWaiting->value() + 1);
    m_threadsActive->setValue(m_threadsActive->maximum() - m_threadsWaiting->value());
}

void MainWindow::waitingThreadNumberDecreased()
{
    m_threadsWaiting->setValue(m_threadsWaiting->value() - 1);
    m_threadsActive->setValue(m_threadsActive->maximum() - m_threadsWaiting->value());
}
